package icom.acm.util.model;

import icom.acm.util.DBConnect;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

/**
 * 
 * @author shench
 * 封装bean类
 */
public class Bean {
	protected Class<?> cls;
	protected Field[] fields;
	protected Method[] methods;
			
	public Bean(){
		launch();
	}
	
	private void launch(){
		cls = this.getClass();
		methods = cls.getMethods();
		fields = cls.getDeclaredFields();		
	}
	
	public void set(DBObject obj){		
		try {
			int len = fields.length;			
			for (int i=0;i<len;i++){			
				Class<?> type = fields[i].getType();
				reflect(cls, 
					"set"+fields[i].getName(), 
					new Class[]{type},
					obj.get(fields[i].getName())
				);									
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}
	
	public Object get(Field field){		
		String name = field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
		Object obj = reflect(cls, "get"+name, new Class[]{});
		
		return obj;
	}

	
	@SuppressWarnings("finally")
	public DBObject getDBObject(){
		DBObject res = new BasicDBObject();
		try {
			int len = fields.length;			
			for (int i=0;i<len;i++){			
				Class<?> type = fields[i].getType();
				Object obj =reflect(cls, 
					"get"+fields[i].getName(), 
					new Class[]{}					
				);
				if (type==java.util.Date.class){
					obj = icom.acm.util.DateUtil.d2s("yyyy年MM月dd日 HH小时mm分钟ss秒",(java.util.Date)obj);
				}
				res.put(fields[i].getName(), obj);
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} finally {
			return res;
		}
	}
	
	public void set(DBConnect db){		
		try {
			int len = fields.length;
			for (int i=0;i<len;i++){			
				Class<?> type = fields[i].getType();
				reflect(cls, "set"+fields[i].getName(), 
					new Class[]{type},
				db.getObj(fields[i].getName()) );									
			}
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/** 
	 * <pre> 
	 * <h3>通过反射执行某个方法，并将数据集放入cache中</h3> 
	 * </pre> 
	 *  
	 * 方法实现呆完成 
	 *  
	 * @param key 
	 *            缓存key 
	 * @param _class 
	 *            类名 
	 * @param methodName 
	 *            类方法名 
	 * @param paramType 
	 *            方法参数类型 
	 * @param args 
	 *            方法参数值 
	 */  
	@SuppressWarnings("finally")
	public Object reflect(Class<?> _class, String methodName,  
	        Class<?>[] paramType, Object... args) {
		Object object = null;
	    try {  
	        // cache判断  
	        // 如果cache中没有这个值，则调用方法填充cache  	    	
	        Method method = _class.getMethod(methodName, paramType);
	        method.setAccessible(true);
System.out.println(method.getName());	        
	        object = method.invoke(this, args);	        
	    } catch (SecurityException e) {  
	        e.printStackTrace();  
	    } catch (NoSuchMethodException e) {  
	        e.printStackTrace();  
	    } catch (IllegalArgumentException e) {  
	        e.printStackTrace();  
	    } catch (IllegalAccessException e) {  
	        e.printStackTrace();  
	    } catch (InvocationTargetException e) {  
	        e.printStackTrace();  
	    } finally {
			return object;
		}
	} 
	
	public String toJson(){
		String json = "{";
		boolean flag = false;
		for(Field field:fields){
			if (flag) json = json + ",";
			flag = true;
			Object value = get(field);
			if (field.getType() == java.util.Date.class){
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd天 HH小时mm分钟ss秒");
				
				value = sdf.format((java.util.Date)value);
			}
			json = json + "\""+field.getName()+"\":\""+value+"\"";			
		}
		json = json + "}";
		return json;
	}	
	/**
	 * 查询sql语句 params为where的键值
	 * @param params 键值
	 * @return
	 */
	public String toSqlSelectEqual(Map<String, Object> params){
		String sql= "SELECT ";
		boolean flag = false;
		for(Field field:fields){
			if (flag) sql = sql + ", ";
			flag = true;
			sql = sql + field.getName();			
		}
		sql = sql + " FROM " + cls.getSimpleName();
		if (params==null) return sql;		
		Set<Entry<String, Object>> set = params.entrySet();
		Iterator<Entry<String, Object>> it = set.iterator();
		flag = false;
		while (it.hasNext()){
			Entry<String, Object> en = it.next();
			if (flag) sql = sql + " AND";
			else sql = sql + " WHERE ";
			flag = true;
			sql = sql + en.getKey().toUpperCase() + "='" + en.getValue().toString() + "'";
		}
		return sql;
	}
	
	public String toSqlUpdate(Map<String, Object> arg, Map<String, Object> params){
		String sql = "UPDATE " + cls.getSimpleName() + " SET";		
		boolean flag = false;
		// set值
		Set<Entry<String, Object>> set_arg = arg.entrySet();
		Iterator<Entry<String, Object>> it_arg = set_arg.iterator();		
		while (it_arg.hasNext()){
			Entry<String, Object> en = it_arg.next();
			if (flag) sql = sql + ", ";
			else sql = sql + " ";
			flag = true;
			sql = sql + en.getKey().toUpperCase() + "='" + en.getValue().toString() + "'";
		}
		// where
		Set<Entry<String, Object>> set_params = params.entrySet();
		Iterator<Entry<String, Object>> it_params = set_params.iterator();		
		while (it_params.hasNext()){
			Entry<String, Object> en = it_params.next();
			if (flag) sql = sql + " AND ";
			else sql = sql + " WHERE ";
			flag = true;
			sql = sql + en.getKey().toUpperCase() + "='" + en.getValue().toString() + "'";
		}
		return sql;
	}
}
